
/**
 @ Name：layui.asynTreeSelect 异步树形选择器
 @ Author：楼顶的向日葵
 @ 版本1.0
 @ 2020年5月27日
 */

layui.define(['form','element'], function(exports){
    var $ = layui.$
        ,form = layui.form
        ,element = layui.element
        //字符常量
        ,MOD_NAME = 'asynTreeSelect', ELEM = '.layui-asynTreeSelect'
        //外部接口
        ,asynTreeSelect  = {
            index: layui.asynTreeSelect ? (layui.asynTreeSelect.index + 10000) : 0
            //设置全局项
            ,set: function(options){
                var that = this;
                that.config = $.extend({}, that.config, options);
                return that;
            }

            //事件监听
            ,on: function(events, callback){
                return layui.onevent.call(this, MOD_NAME, events, callback);
            }
        }

        //操作当前实例
        ,thisIns = function(){
            var that = this
                ,options = that.config
                ,id = options.id || options.index;

            return {
                reload: function(options){
                    that.config.defaultValue=options.defaultValue;
                    $("#"+that.elementId).val(options.defaultValue);
                    $("#"+that.dataUlId +" li").remove();
                    $("#"+that.contentId).empty();
                    _getNextDatas(that,that.config.rootNodeValue,true);
                }
                ,config: options
                ,setValue:function(value){

                }
            }
        }

        //构造器
        ,Class = function(options){
            var that = this;
            that.index = ++asynTreeSelect.index;
            that.config = $.extend({}, that.config, asynTreeSelect.config, options);
            var $elem=$(that.config.elem);
            var deVal=$elem.val();
            var jsDeval=that.config.defaultValue;
            if(jsDeval==null || jsDeval==undefined || jsDeval.toString().length==0)
                that.config.defaultValue=deVal;
            var elementId=$elem.prop("id");
            //that.config.maxWidth=$elem.width()*2;
            var tempTime=new Date().getTime();
            that.elementId=elementId
            that.outDivId=elementId+"_a"+tempTime;
            that.displayInputId=elementId+"_b"+tempTime;
            that.dataDivId=elementId+"_c"+tempTime;
            that.closeImgId=elementId+"_d"+tempTime;
            that.refreshImgId=elementId+"_e"+tempTime;
            that.dataTabLayFilter=elementId+"_f"+tempTime;
            that.dataUlId=elementId+"_g"+tempTime;
            that.contentId=elementId+"_h"+tempTime;
            that.render();
        };

    //默认配置
    Class.prototype.config = {
        paramName: "currNodeId" //
        ,maxWidth:null
        ,rootNodeValue:null
        ,defaultValue:null
        ,toolbar:false
        ,showRootNode:true
        ,separator:null
        ,getCurrentNodeUrl: "data.json" //
        ,getChildrenNodeUrl: "data.json" //
        ,getBrotherNodeUrl: "data.json" //
        ,response:{
            idName:"ID"
            ,valueName:"NAME"
            ,parentName:"PARENT_ID"
        }
        ,onlick:$.noop
        ,beforeRequest:$.noop
        ,parseData:$.noop
    };

    //渲染视图
    Class.prototype.render = function(){
        var that = this
            ,options = that.config;
        options.elem = $(options.elem);
        var elemTmp=options.elem;

        var placeholder=elemTmp.attr("placeholder")?elemTmp.attr("placeholder"):"";
        var valueTagIdStyle=elemTmp.attr("style");

        var clearTagId=that.elementId+"_ci"+new Date().getTime();
        var stylecss=""
        if(valueTagIdStyle)
            stylecss="style=\""+valueTagIdStyle+"\" ";
        var divStr="<div id=\""+that.outDivId+"\"  class=\"layui-unselect layui-form-select\" "+stylecss+" >";
        divStr+="<div class=\"layui-select-title\" >";
        divStr+="<input id=\""+that.displayInputId+"\"  type=\"text\" placeholder=\""+placeholder+"\" readonly=\"\" class=\"layui-input\" >";
        divStr+="<i class=\"layui-icon layui-unselect layui-tab-close\"";
        divStr+="style=\"cursor: pointer;position: absolute;right: 25px;top: 50%; margin-top: -9px;color:#CCCCCC;\"";
        divStr+="id=\""+clearTagId+"\">&#x1006;</i>";
        divStr+="<i class=\"layui-edge\"></i>";
        divStr+="</div>";
        divStr+="</div>";
        elemTmp.prop("type","hidden");
        elemTmp.after(divStr);

        $("#"+clearTagId).click(function(){
            $("#"+that.elementId).val("");
            $("#"+that.displayInputId).val("");
            $("#"+that.outDivId).removeClass("layui-form-selected");

        })

        var tempTime=new Date().getTime();
        var tabTitleUlId="titleUl"+tempTime;
        var dlStr="<dl id='ddddddd' style=\"padding: 0px 0px;max-height: 350px;\" >";
        dlStr+="<div id=\""+that.dataDivId+"\" class=\"layui-tab\" lay-filter=\""+that.dataTabLayFilter+"\" style=\"margin:initial;\">";
        dlStr+="<ul id=\""+that.dataUlId+"\" class=\"layui-tab-title\">";
        if(that.config.toolbar)
            dlStr+=" <span style=\"position: absolute;right:0;z-index:11\"  ><i  title='刷新' id=\""+that.refreshImgId+"\" style=\"cursor: pointer; font-size:13px;\" class=\"layui-icon\">&#xe669;</i><i  title='关闭' id=\""+that.closeImgId+"\" style=\"cursor: pointer;\" class=\"layui-icon\">&#x1006;</i>";
        dlStr+="</ul>";
        dlStr+="<div id=\""+that.contentId+"\" class=\"layui-tab-content\" style=\"padding:initial;\">";
        dlStr+="</div>";
        dlStr+="</div>";
        dlStr+="</dl>";

        $("#"+that.outDivId).append(dlStr);

        if(that.config.maxWidth)
            $("#"+that.dataDivId).parent().css("max-width",that.config.maxWidth);//最大宽度值

        $("#"+that.displayInputId).click(that.outDivId,_divTagClickDefault);//绑定点击事件
        if(that.config.toolbar){
            $("#"+that.closeImgId).click(that.outDivId,_divTagClickDefault);//绑定关闭事件
            $("#"+that.refreshImgId).click(function(e){//绑定刷新事件
                //阻止冒泡事件
                layui.stope(e);
                $("#"+that.dataUlId +" li").remove();
                $("#"+that.contentId).empty();
                _getNextDatas(that,that.config.rootNodeValue,true);
            })
        }

        element.render("tab");
        element.on('tab('+that.dataTabLayFilter+')', function(data){
            var clickLi=$(this);
            var curLiObj=$(this).data("curObj");
            var loadData=$(this).data("loadData");
            if(loadData){
                var indexTab=data.index;
                var  params =new Object();
                params[that.config.paramType]=3;
                var currVal=curLiObj[that.config.response.idName];
                var postUrl=that.config.getBrotherNodeUrl;
                if(currVal==that.config.rootNodeValue){//获取本节点
                    postUrl=that.config.getCurrentNodeUrl;
                    params[that.config.paramType]=1;
                }
                params.currNodeId=currVal;
                $(this).removeData("loadData");
                //加载兄弟节点
                that.config.beforeRequest.call(that,params);
                $.ajax({
                    url:postUrl
                    ,dataType: "json"
                    ,type:"POST"
                    ,data:params
                    ,success:function(datasRes){
                        that.config.parseData.call(that,datasRes);
                        var newItmeDiv=$("#"+that.contentId +" div").eq(indexTab);
                        var idName=that.config.response.idName;
                        var valueName=that.config.response.valueName;
                        var $newEleDl=$("<dl   class=\"layui-anim layui-anim-upbit\" style=\"position:initial;padding:initial;box-shadow:initial;border:initial;\"></dl>");
                        $(newItmeDiv).html($newEleDl);
                        for(var i=0;i<datasRes.length;i++){
                            var curObj=datasRes[i];
                            var $newEleDd=$("<dd lay-value=\""+curObj[idName]+"\" >"+curObj[valueName]+"</dd>");
                            if(currVal && currVal==curObj[idName]){
                                $newEleDd.addClass("layui-this");
                            }
                            $newEleDd.data("curObj",curObj);
                            $newEleDl.append($newEleDd);
                        }

                        //绑定点击事件
                        $newEleDl.find("dd").click(function(e){
                            layui.stope(e);
                            //删掉后面的tab
                            clickLi.nextAll("li").remove();
                            $(newItmeDiv).nextAll("div.layui-tab-item").remove();

                            var jqObj=$(this);
                            jqObj.siblings().removeClass("layui-this");
                            jqObj.addClass("layui-this");
                            var curTmpObj=$(this).data("curObj");
                            //赋值
                            var curVal=curTmpObj[that.config.response.idName];
                            var curName=curTmpObj[that.config.response.valueName];
                            var elemCur=that.config.elem;
                            $("#"+that.elementId).val(curVal);
                            clickLi.attr("lay-id",curVal);
                            clickLi.text(curName);
                            if(that.config.separator){
                                var lis=clickLi.parent().find("li");
                                if(lis && lis.length>0){
                                    var curNames="";
                                    for(var j=0;j<lis.length;j++){
                                        curNames+=that.config.separator+lis[j].innerText;
                                    }
                                    curNames=curNames.substring(that.config.separator.toString().length)
                                }
                                $("#"+that.displayInputId).val(curNames);
                            }else{
                                $("#"+that.displayInputId).val(curName);
                            }


                            that.config.onlick.call(that,curTmpObj);//调用自定义方法
                            _getNextDatas(that,curVal,false);
                        })
                    }
                })
            }
        });
        //第一次请求
        _getNextDatas(that,that.config.rootNodeValue,true);

        $(document).bind("click", function (e) {
            var target = $(e.target);
            if (target.closest("#"+that.outDivId).length == 0 ) {
                $("#"+that.outDivId).removeClass("layui-form-selected");
            }
        });
    }

    //核心入口
    asynTreeSelect.render = function(options){
        var ins = new Class(options);
        return thisIns.call(ins);
    };

    /*  //加载组件所需样式
      layui.link(layui.cache.base + 'asynTreeSelect/asynTreeSelect.css?v=1', function(){
        //样式加载完毕的回调

      }, 'asynTreeSelect'); //此处的“asynTreeSelect”要对应 asynTreeSelect.css 中的样式： html #layuicss-asynTreeSelect{}
    */ //div的点击事件
    _divTagClickDefault=function(event){
        if($("#"+event.data).hasClass("layui-form-selected")){
            $("#"+event.data).removeClass("layui-form-selected");
        }else{
            $("#"+event.data).addClass("layui-form-selected");
        }
        var dlEle=$("#"+event.data).children("dl")[0];
        var dlHeight= $(dlEle).height();
        if(dlHeight>10000){
            $(dlEle).height(500);
        }
    }
    _liClick=function(obj,that){
        element.tabChange(that.dataTabLayFilter,$(obj).attr("lay-id"))
    }
    //获取当前数据
    _getNextDatas=function(that,currNodeId,isFirst){
        //隐藏当前tab
        $("#"+that.outDivId+" .layui-show").removeClass("layui-show");
        $("#"+that.dataUlId+" .layui-this").removeClass("layui-this");

        var tempTimeTitle=new Date().getTime();
        var successDl="sucDl_"+tempTimeTitle;
        var titleLi="titleLi_"+tempTimeTitle;
        var newItemUl="itemUl"+tempTimeTitle;
        var newItemLiTitle="itemLi_"+tempTimeTitle;
        var newItmeDivId="itmeDiv_"+tempTimeTitle;
        var liJq=$("<li id=\""+titleLi+"\" class=\"layui-this\" lay-id=\""+titleLi+"\"  >请选择</li>");
        $("#"+that.dataUlId).append(liJq);
        liJq.click(function(e){
            layui.stope(e);
            _liClick(this,that);
        })

        var divshowStr="";
        divshowStr+="<div id=\""+newItmeDivId+"\" class=\"layui-tab-item layui-show\" >";
        divshowStr+="<ul id=\""+newItemUl+"\"    >";
        divshowStr+="<li  ><i class=\"layui-icon layui-icon-loading layui-icon layui-anim layui-anim-rotate layui-anim-loop\" ></i> </li>";
        divshowStr+="</ul>";
        divshowStr+="</div>";
        $("#"+that.contentId).append(divshowStr);
        element.render("tab");
        var postUrl="";
        var params=new Object();
        if(isFirst){//第一次请求
            //判断是否有默认值
            var defVal=that.config.defaultValue;
            var tagValue=$(that.config.elem).val();
            if(tagValue!=null && tagValue.toString().length>0)defVal=tagValue;
            if(defVal!=null && defVal.toString().length>0){//标签有值
                var resultObj={count:0,list:[],isFindRoot:false};
                _dealDefaultValue(that,defVal,resultObj,titleLi,newItmeDivId,successDl,isFirst,currNodeId);
                return;
            }else{//没默认值
                if(that.config.showRootNode){//如果显示根节点
                    postUrl=that.config.getCurrentNodeUrl;
                    params[that.config.paramType]=1;
                }else{
                    postUrl=that.config.getChildrenNodeUrl;
                    params[that.config.paramType]=2;
                }
                params[that.config.paramName]=currNodeId;

            }
        }else{
            if(that.config.beforeRequest)
                that.config.beforeRequest.call(that,params);
            postUrl=that.config.getChildrenNodeUrl;//获取子节点
            params[that.config.paramType]=2;
            params[that.config.paramName]=currNodeId;
        }
        _getLidata(postUrl,params,that,titleLi,newItmeDivId,successDl,isFirst,currNodeId);



    }
    _getLidata=function(postUrl,params,that,titleLi,newItmeDivId,successDl,isFirst,currNodeId){
        $.ajax({
            url:postUrl
            ,dataType: "json"
            ,type:"POST"
            ,data:params
            ,success:function(datasRes){
                // that.config.parseData.call(that,msg);
                var idName=that.config.response.idName;
                var valueName=that.config.response.valueName;
                if(!isFirst && (!datasRes|| datasRes.length==0)){//不是第一次，没数据关闭
                    //删掉后面的tab
                    $("#"+titleLi).remove();
                    $("#"+newItmeDivId).remove();
                    element.tabChange(that.dataTabLayFilter,currNodeId);
                    $("#"+that.outDivId).removeClass("layui-form-selected");
                    return;
                }
                if(datasRes){
                    var $newEleDl=$("<dl id=\""+successDl+"\" class=\"layui-anim layui-anim-upbit\" style=\"position:initial;padding:initial;box-shadow:initial;border:initial;\"></dl>");
                    $("#"+newItmeDivId).html($newEleDl);
                    if(datasRes.length==0){
                        var $newEleDd=$("<dd lay-value=\"\" style=\"text-align: center;\" class=\"layui-select-tips\">无数据</dd>");
                        $newEleDl.append($newEleDd);
                        return;
                    }
                    for(var i=0;i<datasRes.length;i++){
                        var curObj=datasRes[i];
                        var $newEleDd=$("<dd lay-value=\""+curObj[idName]+"\" >"+curObj[valueName]+"</dd>");

                        $newEleDd.data("curObj",curObj);
                        $newEleDl.append($newEleDd);
                        //绑定点击事件

                        $newEleDd.click(function(e){
                            layui.stope(e);
                            //删掉后面的tab
                            $("#"+titleLi).nextAll("li").remove();
                            $("#"+newItmeDivId).nextAll("div.layui-tab-item").remove();

                            var jqObj=$(this);
                            jqObj.siblings().removeClass("layui-this");
                            jqObj.addClass("layui-this");
                            var curTmpObj=$(this).data("curObj");
                            //赋值
                            var curVal=curTmpObj[that.config.response.idName];
                            var curName=curTmpObj[that.config.response.valueName];
                            var elemCur=that.config.elem;
                            $("#"+that.elementId).val(curVal);
                            $("#"+titleLi).text(curName);
                            $("#"+titleLi).attr("lay-id",curVal);
                            if(that.config.separator){
                                var lis=$("#"+titleLi).parent().find("li");
                                if(lis && lis.length>0){
                                    var curNames="";
                                    for(var j=0;j<lis.length;j++){
                                        curNames+=that.config.separator+lis[j].innerText;
                                    }
                                    curNames=curNames.substring(that.config.separator.toString().length)
                                }
                                $("#"+that.displayInputId).val(curNames);
                            }else{
                                $("#"+that.displayInputId).val(curName);
                            }


                            that.config.onlick.call(that,curTmpObj);//调用自定义方法
                            _getNextDatas(that,curVal,false);
                        })
                    }

                }
            }
        })
    }
    _dealDefaultValue=function(that,currNodeId,resultObj,titleLi,newItmeDivId,successDl,isFirst){
        debugger;
        var params=new Object();
        params[that.config.paramType]=1;
        params[that.config.paramName]=currNodeId;
        $.ajax({
            url:that.config.getCurrentNodeUrl
            ,dataType: "json"
            ,type:"POST"
            ,data:params
            ,success:function(msg){
                debugger;
                var idName=that.config.response.idName;
                var valueName=that.config.response.valueName;
                var parentName=that.config.response.parentName;
                if(msg && msg.length>0  ){
                    if(resultObj.count>100)return;//递归次数禁止超过100次
                    resultObj.count=resultObj.count+1;
                    var currObj=msg[0];
                    resultObj.list.push(currObj);
                    var parentId= currObj[parentName];
                    var breakNodeFlag=null;
                    if(that.config.showRootNode){//显示根节点
                        breakNodeFlag=idName;
                    }else{//不显示根节点
                        breakNodeFlag=parentName;
                    }
                    if(currObj[breakNodeFlag]==that.config.rootNodeValue ){//到达根节点，跳出递归
                        //处理默认值
                        $("#"+that.contentId).empty();
                        var $dataUl=$("#"+that.dataUlId);
                        $dataUl.empty();
                        var defaultValArr=resultObj.list;
                        var dispalyNames="";
                        for(var k=defaultValArr.length-1;k>=0;k--){
                            var defaultValObj=defaultValArr[k];
                            var name=defaultValObj[valueName];
                            var idVal=defaultValObj[idName];
                            dispalyNames+=that.config.separator+name;

                            var $li=$("<li lay-id='"+idVal+"'   >"+name+"</li>");
                            $li.data("curObj",defaultValObj);
                            $li.data("loadData",true);
                            $dataUl.append($li);
                            $li.click(function(e){
                                layui.stope(e);
                                _liClick(this,that);
                            })
                            var divshowStr="";
                            divshowStr+="<div id=\"item_"+defaultValObj[idName]+"\" class=\"layui-tab-item\" >";
                            divshowStr+="<ul  >";
                            divshowStr+="<li  ><i class=\"layui-icon layui-icon-loading layui-icon layui-anim layui-anim-rotate layui-anim-loop\" ></i> </li>";
                            divshowStr+="</ul>";
                            divshowStr+="</div>";
                            $("#"+that.contentId).append(divshowStr);
                            if(k==0){//设置默认值
                                $("#"+that.elementId).val(idVal);
                                dispalyNames=dispalyNames.substring(that.config.separator.toString().length);
                                $("#"+that.displayInputId).val(dispalyNames);
                                //加载兄弟节点
                                element.tabChange(that.dataTabLayFilter,idVal);
                            }
                        }

                        element.render("tab");

                        return;
                    }else if( currObj[idName]==currObj[parentName] || currObj[parentName]==null){
                        var postUrl="";
                        var params=new Object();
                        //没默认值
                        if(that.config.showRootNode){//如果显示根节点
                            postUrl=that.config.getCurrentNodeUrl;
                            params[that.config.paramType]=1;
                        }else{
                            postUrl=that.config.getChildrenNodeUrl;
                            params[that.config.paramType]=2;
                        }
                        params[that.config.paramName]=that.config.rootNodeValue;
                        _getLidata(postUrl,params,that,titleLi,newItmeDivId,successDl,isFirst,currNodeId);


                        return;
                    }else{//继续查找父节点
                        _dealDefaultValue(that,parentId,resultObj,titleLi,newItmeDivId,successDl,isFirst);
                    }


                }else{
                    var postUrl="";
                    var params=new Object();
                    //没默认值
                    if(that.config.showRootNode){//如果显示根节点
                        postUrl=that.config.getCurrentNodeUrl;
                        params[that.config.paramType]=1;
                    }else{
                        postUrl=that.config.getChildrenNodeUrl;
                        params[that.config.paramType]=2;
                    }
                    params[that.config.paramName]=that.config.rootNodeValue;
                    _getLidata(postUrl,params,that,titleLi,newItmeDivId,successDl,isFirst,currNodeId);
                }
            }
        })
    }

    exports('asynTreeSelect', asynTreeSelect);
});